/*
 * commandParser.cpp
 *
 *  Created on: 21.11.2011
 *      Author: delgado
 */

#include "commandParser.h"
#include <iostream>
using std::cout;
using std::endl;
#include "error.h"
using neurignacio::error;

#include <boost/program_options.hpp>
#include <boost/any.hpp>

namespace TIDA
{

commandOptions::commandOptions(int argc, char* argv[])
	: forceOverwrite(false), verbose(false), fileStructure(false), help(false), amplpar(-1)
{


	const string HELP_OPTION = "help";
	const string HELP_OPTION_SHORT = "h";
	const string HELP_OPTION_DESCRIPTION="Print this help screen and exit";
	const string OUTPUT_FILE_OPTION = "output-file";
	const string OUTPUT_FILE_OPTION_SHORT = "o";
	const string OUTPUT_FILE_OPTION_DESCRIPTION="Set output filename\n  Default output format:\n  {input-file}_extension_c{channel-number}.tida.txt\n  example: ID771201_034_c1.tida.txt";
	const string INPUT_FILE_OPTION = "input-file";
	const string INPUT_FILE_OPTION_SHORT = "i";
	const string INPUT_FILE_OPTION_DESCRIPTION="Set explicitly input filename\n  example: --input-file=ID771201.034\nThe input filename can be also given directly without any option";
	const string OVERWRITE_OPTION = "force";
	const string OVERWRITE_OPTION_SHORT = "f";
	const string OVERWRITE_OPTION_DESCRIPTION="Force overwriting the destination file";
	const string VERBOSE_OPTION = "vebose";
	const string VERBOSE_OPTION_SHORT = "v";
	const string VERBOSE_OPTION_DESCRITPION = "Increase verbosity";
	const string FILE_STRUCTURE_OPTION = "file-structure";
	const string FILE_STRUCTURE_OPTION_SHORT = "s";
	const string FILE_STRUCTURE_OPTION_DESCRIPTION = "display file structure (useful for debugging) and exit";
	const string INFO_OPTION = "Whole-Info";
	const string INFO_OPTION_SHORT = "W";
	const string INFO_OPTION_DESCRIPTION = "display whole information for the file and exit\nEquivalent to -HRSCA";
	const string HEADER_OPTION = "header";
	const string HEADER_OPTION_SHORT = "H";
	const string HEADER_OPTION_DESCRIPTION = "display Header information for the file and exit";
	const string RECPAR_OPTION = "recpar";
	const string RECPAR_OPTION_SHORT = "R";
	const string RECPAR_OPTION_DESCRIPTION = "display Recording Parameters for the file and exit";
	const string SCALPAR_OPTION = "scalpar";
	const string SCALPAR_OPTION_SHORT = "S";
	const string SCALPAR_OPTION_DESCRIPTION = "display Scaling Parameters for the file and exit";
	const string COMMENTS_OPTION = "comments";
	const string COMMENTS_OPTION_SHORT = "C";
	const string COMMENTS_OPTION_DESCRIPTION = "display Comments for the file and exit";
	const string AMPLPAR_OPTION = "amplpar";
	const string AMPLPAR_OPTION_SHORT = "A";
	const string AMPLPAR_OPTION_DESCRIPTION = "display Amplifier Parameters for the file and exit\narg:  Amplifier Number (0 for displaying all)";


	// Check if there are any options
	if (argc<=1)
		{
			string errorString="Missing command options\n";
			errorString += "Please refer to the help for use instructions ( ";
			errorString += argv[0];
			errorString += " --help or ";
			errorString += argv[0];
			errorString += "-h )";
			error(neurignacio::NO_ARGUMENTS,errorString);
		}

	const string USAGE_DESCRIPTION = "\nUsage: "+string(argv[0])+" [options] input-file\n";
	const string EXAMPLES = "Examples:\n  "+string(argv[0])+" -fv ID771201.034\n  Converts the file to ID7701201_034_c1.tida.txt overwriting destination and informs about what it does\n";
	const string OPTIONS_HEADER = "Options Supported:";
	try
	{
		boost::program_options::options_description desc(string(USAGE_DESCRIPTION+EXAMPLES+"\n"+OPTIONS_HEADER).c_str());
		desc.add_options()
				(string(HELP_OPTION+","+HELP_OPTION_SHORT).c_str(), HELP_OPTION_DESCRIPTION.c_str())
				(string(OUTPUT_FILE_OPTION+","+OUTPUT_FILE_OPTION_SHORT).c_str(), boost::program_options::value< string >(), OUTPUT_FILE_OPTION_DESCRIPTION.c_str())
				(string(INPUT_FILE_OPTION+","+INPUT_FILE_OPTION_SHORT).c_str(), boost::program_options::value< string >(), INPUT_FILE_OPTION_DESCRIPTION.c_str())
				(string(OVERWRITE_OPTION+","+OVERWRITE_OPTION_SHORT).c_str(), OVERWRITE_OPTION_DESCRIPTION.c_str())
				(string(VERBOSE_OPTION+","+VERBOSE_OPTION_SHORT).c_str(), VERBOSE_OPTION_DESCRITPION.c_str())
				(string(FILE_STRUCTURE_OPTION+","+FILE_STRUCTURE_OPTION_SHORT).c_str(), FILE_STRUCTURE_OPTION_DESCRIPTION.c_str())
				(string(INFO_OPTION+","+INFO_OPTION_SHORT).c_str(), INFO_OPTION_DESCRIPTION.c_str())
				(string(HEADER_OPTION+","+HEADER_OPTION_SHORT).c_str(), HEADER_OPTION_DESCRIPTION.c_str())
				(string(RECPAR_OPTION+","+RECPAR_OPTION_SHORT).c_str(), RECPAR_OPTION_DESCRIPTION.c_str())
				(string(SCALPAR_OPTION+","+SCALPAR_OPTION_SHORT).c_str(), SCALPAR_OPTION_DESCRIPTION.c_str())
				(string(COMMENTS_OPTION+","+COMMENTS_OPTION_SHORT).c_str(), COMMENTS_OPTION_DESCRIPTION.c_str())
				(string(AMPLPAR_OPTION+","+AMPLPAR_OPTION_SHORT).c_str(), boost::program_options::value<int>(), AMPLPAR_OPTION_DESCRIPTION.c_str())
		;
		boost::program_options::positional_options_description p;
		p.add(INPUT_FILE_OPTION.c_str(), -1);

		boost::program_options::variables_map vm;
		boost::program_options::store(boost::program_options::command_line_parser(argc,argv).options(desc).positional(p).run(), vm);
		boost::program_options::notify(vm);

		if (vm.count(HELP_OPTION))
		{
			help = true;
			cout << desc << "\n";
		}
		if (vm.count(OUTPUT_FILE_OPTION))
			outputFile= vm[OUTPUT_FILE_OPTION].as< string >();

		if (vm.count(INPUT_FILE_OPTION))
			inputFile=vm[INPUT_FILE_OPTION].as< string >();


		if (vm.count(OVERWRITE_OPTION))
			forceOverwrite=true;

		if (vm.count(VERBOSE_OPTION))
			verbose=true;

		if (vm.count(FILE_STRUCTURE_OPTION))
			fileStructure=true;

		if (vm.count(HEADER_OPTION))
			header=true;
		if (vm.count(RECPAR_OPTION))
			recpar=true;
		if (vm.count(SCALPAR_OPTION))
			scalpar=true;
		if (vm.count(COMMENTS_OPTION))
			comments=true;
		if (vm.count(AMPLPAR_OPTION))
			amplpar=vm[AMPLPAR_OPTION].as<int>();
		if (vm.count(INFO_OPTION))
		{
			header=true;
			recpar=true;
			scalpar=true;
			comments=true;
			amplpar=0;
		}
	}
	catch (boost::program_options::error option)
	{
		error(neurignacio::COMMAND_PARSER_EXCEPTION, option.what());
	}
}

ostream& operator<<(ostream& out, const commandOptions& cmd)
{
	out.setf(std::ios::boolalpha);
	out << "\tCommand Options: " << endl;
	out << "\tInput File: " << cmd.inputFile << endl;
	out << "\tOutput File: " << cmd.outputFile << endl;
	out << "\tOverwrite? " << cmd.forceOverwrite << endl;
	out << "\tVerbose? " << cmd.verbose << endl;
	out << "\tHeader? " << cmd.header << endl;
	out << "\tRecpar? " << cmd.recpar << endl;
	out << "\tScalpar? " << cmd.scalpar << endl;
	out << "\tComments? " << cmd.comments << endl;
	out << "\tAmplpar? " << cmd.amplpar << endl;
	out << "\tFile Structure? " << cmd.fileStructure << endl;
	out << "\tHelp? " << cmd.help << endl;
//	out.setf(std::ios::noboolalpha) << endl;
	return out;
}

} // end namespace TIDA

